// 函数式编程 核心是组合 （把函数编程一个个的小函数） 在组合在一起

// 柯里化 转化技术  将多参数的函数 转化成单参数的函数。 标准的柯里化 强调的是，转化后的函数参数是一个个的
// 如果是分批传入，偏函数 : 先固定一部分参数，返回一个函数 ， 在传入剩下的一部分。

// function sum(a, b, c) {}
// function sum(a) {
//   return function (b, c) {};
// }

// function isType(typing, val) {
//   return Object.prototype.toString.call(val) === `[object ${typing}]`;
// }

// 粒度
/*
function isType(typing) {
  return function (val) {
    return Object.prototype.toString.call(val) === `[object ${typing}]`;
  };
}
let isString = isType("String"); // 拆成多个小函数
console.log(isString("abc"));
console.log(isString(123));
*/

// let isString1 = isType("String", "123");
// console.log(isString1);

// let isString2 = isType("Number", "123");
// console.log(isString2);

// 如何实现一个通用的柯里化函数。
function sum(a, b, c, d) {
  return a + b + c + d;
}
// 将函数进行柯里化
function curry(fn) {
  let curried = (...args) => {
    if (args.length < fn.length) {
      // 传入的参数个数小于函数的参数个数
      return (...other) => curried(...args, ...other); // 否则返回新函数继续等待剩余参数
    }
    return fn(...args); // 和提供的参数个数做对比，如果达到了函数的参数执行
  };
  return curried;
}
let curriedSum = curry(sum);
let fn12 = curriedSum(1, 2);
const fn123 = fn12(3);
const returnVal = fn123(3);
console.log(returnVal);

function isType(typing, val) {
  return Object.prototype.toString.call(val) === `[object ${typing}]`;
}
let curriedIsType = curry(isType);
let isString = curriedIsType("String");
console.log(isString("abc"));
console.log(isString(123));
